package com.linkgie.galaxyframework.httpproxy.core;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HttpHeaders;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.beans.BeanUtils;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

import com.linkgie.galaxyframework.httpproxy.HeaderEntry;
import com.linkgie.galaxyframework.httpproxy.HttpFunction;
import com.linkgie.galaxyframework.httpproxy.HttpMethod;
import com.linkgie.galaxyframework.httpproxy.HttpParams;
import com.linkgie.galaxyframework.httpproxy.HttpRequestDefinition;
import com.linkgie.galaxyframework.httpproxy.HttpRequestDefinition.Body;
import com.linkgie.galaxyframework.httpproxy.HttpRequestDefinition.InputParam;
import com.linkgie.galaxyframework.httpproxy.HttpRequestDefinition.ListParam;
import com.linkgie.galaxyframework.httpproxy.HttpRequestDefinition.Param;
import com.linkgie.galaxyframework.httpproxy.HttpRequestDefinition.PathVariable;
import com.linkgie.galaxyframework.httpproxy.HttpRequestException;
import com.linkgie.galaxyframework.httpproxy.HttpServiceContext;
import com.linkgie.galaxyframework.httpproxy.HttpServiceDefinition;
import com.linkgie.galaxyframework.httpproxy.ParamEntry;
import com.linkgie.galaxyframework.httpproxy.RequestBodyConverter;
import com.linkgie.galaxyframework.httpproxy.RequestParamFilter;
import com.linkgie.galaxyframework.httpproxy.ResponseConverter;
import com.linkgie.galaxyframework.httpproxy.ResponseConverterFactory;
import com.linkgie.galaxyframework.httpproxy.ResponseHandler;
import com.linkgie.galaxyframework.httpproxy.ResponseHandlerFactory;
import com.linkgie.galaxyframework.httpproxy.ServiceInvocationContext;
import com.linkgie.galaxyframework.httpproxy.StringConverter;
import com.linkgie.galaxyframework.httpproxy.annotations.HttpRequest;
import com.linkgie.galaxyframework.httpproxy.annotations.PathParam;
import com.linkgie.galaxyframework.httpproxy.annotations.RequestBody;
import com.linkgie.galaxyframework.httpproxy.annotations.RequestParam;
import com.linkgie.galaxyframework.httpproxy.annotations.RequestParamList;
import com.linkgie.galaxyframework.httpproxy.annotations.ServiceProxy;
import com.linkgie.galaxyframework.httpproxy.converters.DefaultResponseHandlerFactory;
import com.linkgie.galaxyframework.utils.DecodingPipe;
import com.linkgie.galaxyframework.utils.EncodingPipe;
import com.linkgie.galaxyframework.utils.TextUtils;

/**
 * http 服务代理；
 * 
 * @author haiq
 *
 */
public class HttpProxy {

	private static final String DEFAULT_CONTENT_TYPE = "application/json";

	private static final HttpServiceDefinition DEFAUL_HTTP_SERVICE_DEFINITION = new HttpServiceDefinition();

	@SuppressWarnings("unused")
	private static final ParamEntry[] EMPTY_PARAMS = {};

	private static Map<Class<?>, HttpProxy> proxyMap = new ConcurrentHashMap<Class<?>, HttpProxy>();

	private Class<?> serviceClass;

	private RequestBodyConverter defaultRequestBodyConverter;

	private ResponseHandler defaultResponseHandler;

	private ResponseHandlerFactory responseHandlerFactory;

	// 缺陷 2024-07-20 ;
	// HttpProxy 实例被设计为可缓存的对象，因此不能持有与请求实例有关的状态对象—— headersProvider 会因请求的不同而不同；
	// private RequestHeadersProvider headersProvider;

	private Map<Method, HttpActionContext> httpActions = new HashMap<>();

	private HttpActionContext singletonAction;

	private HttpProxy(Class<?> serviceClass) {
		this.serviceClass = serviceClass;

		// 缺陷 2024-07-20 ;
		// HttpProxy 实例被设计为可缓存的对象，因此不能持有与请求实例有关的状态对象—— headersProvider 会因请求的不同而不同；
		// this.headersProvider = headersProvider;

		initHttpService();
	}

	private HttpProxy(HttpServiceDefinition serviceDefinition, HttpRequestDefinition requestDefinition) {
		// 一个HTTP服务中所有请求的路径的公共部分；
		String basePath = initHttpService(serviceDefinition);
		this.singletonAction = createHttpAction(basePath, requestDefinition);
	}

	/**
	 * 创建映射指定服务接口的 HTTP 服务代理；
	 * 
	 * @param serviceClass        服务的接口类型；
	 * @param serviceEndpoint     连接到服务提供者服务器的相关设置；
	 * @param authorizationHeader 安全认证头部；
	 * @return
	 */
	public static <T> T createService(Class<T> serviceClass, HttpAddress serviceEndpoint, HeaderEntry... headers) {
		return createService(serviceClass, serviceEndpoint, null, null, headers);
	}

	/**
	 * 创建映射指定服务接口的 HTTP 服务代理；
	 * 
	 * @param serviceClass    服务的接口类型；
	 * @param serviceEndpoint 服务终结点；
	 * @return
	 */
	public static <T> T createService(Class<T> serviceClass, HttpAddress serviceEndpoint) {
		return createService(serviceClass, serviceEndpoint, (RequestHeadersProvider) null);
	}

	/**
	 * 创建映射指定服务接口的 HTTP 服务代理；
	 * 
	 * @param serviceClass    服务的接口类型；
	 * @param serviceEndpoint 服务终结点；
	 * @param requestEncoder
	 * @param responseDecoder
	 * @return
	 */
	public static <T> T createService(Class<T> serviceClass, HttpAddress serviceEndpoint, EncodingPipe requestEncoder,
			DecodingPipe responseDecoder) {
		return createService(serviceClass, serviceEndpoint, requestEncoder, responseDecoder, null,
				(RequestHeadersProvider) null);
	}

	/**
	 * 创建映射指定服务接口的 HTTP 服务代理；
	 * 
	 * @param serviceClass    定义了服务的接口类型；
	 * @param serviceEndpoint 服务终结点；
	 * @param headersProvider 动态头部的提供函数；可以根据请求生成不同的头部；
	 * @return
	 */
	public static <T> T createService(Class<T> serviceClass, HttpAddress serviceEndpoint,
			RequestHeadersProvider headersProvider) {
		return createService(serviceClass, serviceEndpoint, null, headersProvider);
	}

	/**
	 * 创建映射指定服务接口的 HTTP 服务代理；
	 * 
	 * @param serviceClass        定义了服务的接口类型；
	 * @param serviceEndpoint     服务终结点；
	 * @param authorizationHeader HTTP Basic安全认证头部；
	 * @return
	 */
	public static <T> T createService(Class<T> serviceClass, HttpAddress serviceEndpoint,
			HttpBasicAuthorizationHeader authorizationHeader) {
		RequestHeadersProvider headersProvider = null;
		if (authorizationHeader != null) {
			headersProvider = (request) -> {
				com.linkgie.galaxyframework.httpproxy.HttpHeaders headers = new com.linkgie.galaxyframework.httpproxy.HttpHeaders();
				headers.set(authorizationHeader);
				return headers;
			};
		}
		return createService(serviceClass, serviceEndpoint, null, headersProvider);
	}

	/**
	 * 创建映射指定服务接口的 HTTP 服务代理；
	 * 
	 * @param serviceClass        定义了服务的接口类型；
	 * @param serviceEndpoint     服务终结点；
	 * @param authorizationHeader HTTP Basic安全认证头部；
	 * @return
	 */
	public static <T> T createService(Class<T> serviceClass, HttpAddress serviceEndpoint,
			AuthorizationHeader authorizationHeader) {
		RequestHeadersProvider headersProvider = null;
		if (authorizationHeader != null) {
			headersProvider = (request) -> {
				com.linkgie.galaxyframework.httpproxy.HttpHeaders headers = new com.linkgie.galaxyframework.httpproxy.HttpHeaders();
				headers.set(authorizationHeader);
				return headers;
			};
		}
		return createService(serviceClass, serviceEndpoint, null, headersProvider);
	}

	/**
	 * 创建映射指定服务接口的 HTTP 服务代理；
	 * 
	 * @param serviceClass      定义了服务的接口类型；
	 * @param serviceEndpoint   服务终结点；
	 * @param connectionManager 连接管理器；
	 * @param headersProvider   动态头部的提供函数；可以根据请求生成不同的头部；
	 * @param headers           静态的请求头部；
	 * @return
	 */
	public static <T> T createService(Class<T> serviceClass, HttpAddress serviceEndpoint,
			HttpConnectionManager connectionManager, RequestHeadersProvider headersProvider, HeaderEntry... headers) {
		return createService(serviceClass, serviceEndpoint, null, null, null, headersProvider, headers);
	}

	/**
	 * 创建映射指定服务接口的 HTTP 服务代理；
	 * 
	 * @param serviceClass      定义了服务的接口类型；
	 * @param serviceEndpoint   服务终结点；
	 * @param connectionManager 连接管理器；
	 * @param headersProvider   动态头部的提供函数；可以根据请求生成不同的头部；
	 * @param headers           静态的请求头部；
	 * @return
	 */
	public static <T> T createService(Class<T> serviceClass, HttpAddress serviceEndpoint,
			EncodingPipe requestEncoder, DecodingPipe responseDecoder,
			HttpConnectionManager connectionManager, RequestHeadersProvider headersProvider, HeaderEntry... headers) {
		HttpConnection connection = null;
		if (connectionManager == null) {
			connection = HttpConnectionManager.connect(serviceEndpoint);
		} else {
			connection = connectionManager.create(serviceEndpoint);
		}
		return createService(serviceClass, connection, headersProvider, headers, requestEncoder, responseDecoder, null);
	}

	/**
	 * 创建映射指定服务接口的 HTTP 服务代理；
	 * 
	 * @param serviceClass      定义了服务的接口类型；
	 * @param serviceEndpoint   服务终结点；
	 * @param connectionManager 连接管理器；
	 * @param headersProvider   动态头部的提供函数；可以根据请求生成不同的头部；
	 * @param headers           静态的请求头部；
	 * @return
	 */
	public static <T> T createService(Class<T> serviceClass, HttpConnection connection,
			RequestHeadersProvider headersProvider, HeaderEntry... headers) {
		return createService(serviceClass, connection, headersProvider, headers, null);
	}

	/**
	 * 创建映射指定服务接口的 HTTP 服务代理；
	 * 
	 * @param serviceClass      定义了服务的接口类型；
	 * @param serviceEndpoint   服务终结点；
	 * @param connectionManager 连接管理器；
	 * @param headersProvider   动态头部的提供函数；可以根据请求生成不同的头部；
	 * @param headers           静态的请求头部；
	 * @param bindingData       由调用者指定的绑定对象；<br>
	 *                          该对象将被关联到 HttpServiceContext
	 *                          上；调用者可以通过此对象将某些数据对象传递到调用过程的一些处理组件上，例如
	 *                          {@link ResponseConverter}；
	 * @return
	 */
	public static <T> T createService(Class<T> serviceClass, HttpConnection connection,
			RequestHeadersProvider headersProvider, HeaderEntry[] headers, Object bindingData) {
		return createService(serviceClass, connection, headersProvider, headers, null, null, bindingData);
	}

	/**
	 * 创建映射指定服务接口的 HTTP 服务代理；
	 * 
	 * @param serviceClass      定义了服务的接口类型；
	 * @param serviceEndpoint   服务终结点；
	 * @param connectionManager 连接管理器；
	 * @param headersProvider   动态头部的提供函数；可以根据请求生成不同的头部；
	 * @param headers           静态的请求头部；
	 * @param requestEncoder    请求编码器；可为空；
	 * @param responseDecoder   响应解码器；可为空；
	 * @param bindingData       由调用者指定的绑定对象；<br>
	 *                          该对象将被关联到 HttpServiceContext
	 *                          上；调用者可以通过此对象将某些数据对象传递到调用过程的一些处理组件上，例如
	 *                          {@link ResponseConverter}；
	 * @return
	 */
	public static <T> T createService(Class<T> serviceClass, HttpConnection connection,
			RequestHeadersProvider headersProvider, HeaderEntry[] headers, EncodingPipe requestEncoder,
			DecodingPipe responseDecoder, Object bindingData) {
		if (serviceClass == null) {
			throw new IllegalArgumentException("Service class is null!");
		}
		if (!(connection instanceof HttpProxyConnection)) {
			throw new IllegalArgumentException(
					"Illegal service connection! It must be created by the ServiceConnectionManager!");
		}
		HttpProxyConnection httpConnection = (HttpProxyConnection) connection;

		// 注：20240720
		// 取消对代理对象的缓存，这会导致
		// 避免反复解析同一个服务类型；
		HttpProxy clientProxy = proxyMap.get(serviceClass);
		if (clientProxy == null) {
			synchronized (serviceClass) {
				clientProxy = proxyMap.get(serviceClass);
				if (clientProxy == null) {
					clientProxy = new HttpProxy(serviceClass);
					proxyMap.put(serviceClass, clientProxy);
				}
			}
		}

		ServiceInvocationHandler invocationHandler = new ServiceInvocationHandler(clientProxy, httpConnection,
				headersProvider, headers, requestEncoder, responseDecoder,
				bindingData);

		@SuppressWarnings("unchecked")
		T serviceProxy = (T) Proxy.newProxyInstance(serviceClass.getClassLoader(),
				new Class<?>[] { HttpServiceClient.class, serviceClass }, invocationHandler);
		return serviceProxy;
	}

	/**
	 * 创建 HTTP Delete 请求；
	 * 
	 * @param <T>
	 * @param url     HTTP 服务的 URL；
	 * @param headers 请求的标准头部；每次调用都会包含；
	 * @param params  请求的标准参数；每次调用都会包含；
	 * @return
	 */
	public static HttpFunction<String> createHttpDelete(String url) {
		return createRequest(url, null, HttpMethod.DELETE, null, String.class, null);
	}

	/**
	 * 创建 HTTP Put 请求；
	 * 
	 * @param <T>
	 * @param url     HTTP 服务的 URL；
	 * @param headers 请求的标准头部；每次调用都会包含；
	 * @param params  请求的标准参数；每次调用都会包含；
	 * @return
	 */
	public static HttpFunction<String> createHttpPut(String url) {
		return createRequest(url, null, HttpMethod.PUT, null, String.class, null);
	}

	/**
	 * 创建 HTTP Post 请求；
	 * 
	 * @param <T>
	 * @param url     HTTP 服务的 URL；
	 * @param headers 请求的标准头部；每次调用都会包含；
	 * @param params  请求的标准参数；每次调用都会包含；
	 * @return
	 */
	public static HttpFunction<String> createHttpPost(String url) {
		return createRequest(url, null, HttpMethod.POST, null, String.class, null);
	}

	/**
	 * 创建 HTTP Get 请求；
	 * 
	 * @param <T>
	 * @param url     HTTP 服务的 URL；
	 * @param headers 请求的标准头部；每次调用都会包含；
	 * @param params  请求的标准参数；每次调用都会包含；
	 * @return
	 */
	public static HttpFunction<String> createHttpGet(String url) {
		return createRequest(url, null, HttpMethod.GET, null, String.class, null);
	}

	/**
	 * 初始化 HTTP 请求；
	 * 
	 * @param <T>
	 * @param url     HTTP 请求的 URL；
	 * @param headers 请求的标准头部；每次调用都会包含；
	 * @param method  请求方法；GET/POST/PUT/DELETE 等；
	 * @param params  请求的标准参数；每次调用都会包含；
	 * @return
	 */
	public static HttpFunction<String> createRequest(String url, HttpMethod method) {
		return createRequest(url, null, method, null, String.class, null);
	}

	/**
	 * 初始化 HTTP 请求；
	 * 
	 * @param <T>
	 * @param url     HTTP 请求的 URL；
	 * @param headers 请求的标准头部；每次调用都会包含；
	 * @param method  请求方法；GET/POST/PUT/DELETE 等；
	 * @param params  请求的标准参数；每次调用都会包含；
	 * @return
	 */
	public static HttpFunction<String> createRequest(String url, HttpMethod method,
			Properties params) {
		return createRequest(url, null, method, params, String.class, null);
	}

	/**
	 * 初始化 HTTP 请求；
	 * 
	 * @param <T>
	 * @param url     HTTP 请求的 URL；
	 * @param headers 请求的标准头部；每次调用都会包含；
	 * @param method  请求方法；GET/POST/PUT/DELETE 等；
	 * @param params  请求的标准参数；每次调用都会包含；
	 * @return
	 */
	public static HttpFunction<String> createRequest(String url, Properties headers, HttpMethod method,
			Properties params) {
		return createRequest(url, headers, method, params, String.class);
	}

	/**
	 * 初始化 HTTP 请求；
	 * 
	 * @param <T>
	 * @param url               HTTP 请求的 URL；
	 * @param headers           请求的标准头部；每次调用都会包含；
	 * @param method            请求方法；GET/POST/PUT/DELETE 等；
	 * @param params            请求的标准参数；每次调用都会包含；
	 * @param connectionManager 连接管理器；
	 * @return
	 */
	public static HttpFunction<String> createRequest(String url, Properties headers, HttpMethod method,
			Properties params, HttpConnectionManager connectionManager) {
		return createRequest(url, headers, method, params, String.class, connectionManager);
	}

	/**
	 * 初始化 HTTP 请求；
	 * 
	 * @param <T>          返回值类型；
	 * @param url          HTTP 服务的 URL；
	 * @param headers      请求的标准头部；每次调用都会包含；
	 * @param method       请求方法；GET/POST/PUT/DELETE 等；
	 * @param params       请求的标准参数；每次调用都会包含；
	 * @param responseType 返回值类型；
	 * @return
	 */
	public static <T> HttpFunction<T> createRequest(String url, Properties headers, HttpMethod method,
			Properties params, Class<T> responseType) {
		return createRequest(url, headers, method, params, responseType, null);
	}

	/**
	 * 初始化 HTTP 请求；
	 * 
	 * @param <T>          返回值类型；
	 * @param url          HTTP 服务的 URL；
	 * @param headers      请求的标准头部；每次调用都会包含；
	 * @param method       请求方法；GET/POST/PUT/DELETE 等；
	 * @param params       请求的标准参数；每次调用都会包含；
	 * @param responseType 返回值类型；
	 * @return
	 */
	public static <T> HttpFunction<T> createRequest(String url, Properties headers, HttpMethod method,
			Properties params, Class<T> responseType, EncodingPipe requestEncoder, DecodingPipe responseDecoder) {
		return createRequest(url, headers, method, params, responseType, null, requestEncoder, responseDecoder);
	}

	/**
	 * 初始化 HTTP 服务；
	 * 
	 * @param <T>          返回值类型；
	 * @param url          HTTP 服务的 URL；
	 * @param headers      请求的标准头部；每次调用都会包含；
	 * @param method       请求方法；GET/POST/PUT/DELETE 等；
	 * @param params       请求的标准参数；每次调用都会包含；
	 * @param responseType 返回值类型；
	 * @return
	 */
	public static <T> HttpFunction<T> createRequest(String url, Properties headers, HttpMethod method,
			Properties params, Class<T> responseType, HttpConnectionManager connectionManager) {
		return createRequest(url, headers, method, params, responseType, connectionManager, null, null);
	}

	/**
	 * 初始化 HTTP 服务；
	 * 
	 * @param <T>          返回值类型；
	 * @param url          HTTP 服务的 URL；
	 * @param headers      请求的标准头部；每次调用都会包含；
	 * @param method       请求方法；GET/POST/PUT/DELETE 等；
	 * @param params       请求的标准参数；每次调用都会包含；
	 * @param responseType 返回值类型；
	 * @return
	 */
	public static <T> HttpFunction<T> createRequest(String url, Properties headers, HttpMethod method,
			Properties params, Class<T> responseType, HttpConnectionManager connectionManager,
			EncodingPipe requestEncoder, DecodingPipe responseDecoder) {
		try {
			URL serviceUrl = new URL(url);
			HttpAddress serviceEndpoint = new HttpAddress(serviceUrl.getHost(), serviceUrl.getPort(),
					"https".equalsIgnoreCase(serviceUrl.getProtocol()));

			HttpRequestDefinition requestDefinition = new HttpRequestDefinition();
			requestDefinition.setResponseType(responseType);
			requestDefinition.setHttpMethod(method);
			requestDefinition.setPath(serviceUrl.getPath());

			Properties requestParams = resolveQueryParameters(serviceUrl);
			if (params != null) {
				if (requestParams == null) {
					requestParams = params;
				} else {
					requestParams.putAll(params);
				}
			}

			return createRequest(serviceEndpoint, requestDefinition, headers, requestParams, connectionManager,
					requestEncoder, responseDecoder);
		} catch (MalformedURLException e) {
			throw new IllegalArgumentException(e.getMessage(), e);
		}
	}

	private static Properties resolveQueryParameters(URL serviceUrl) {
		String query = serviceUrl.getQuery();
		if (TextUtils.isBlank(query)) {
			return null;
		}
		// 解析 URL 参数；
		Properties requestParams = new Properties();
		String[] nameValueSections = query.split("\\s*&\\s*");
		for (String nameValueSection : nameValueSections) {
			String[] nameValue = nameValueSection.split("\\s*=\\s*");
			if (nameValue.length == 2) {
				requestParams.put(nameValue[0], nameValue[1]);
			}
		}
		return requestParams;
	}

	/**
	 * 创建请求；
	 * 
	 * @param <T>               返回值类型；
	 * @param serviceEndpoint   服务终结点；
	 * @param requestDefinition 请求定义；
	 * @param headers           标准头部；
	 * @param params            标准参数；
	 * @return
	 */
	public static <T> HttpFunction<T> createRequest(HttpAddress serviceEndpoint,
			HttpRequestDefinition requestDefinition, Properties headers, Properties params,
			HttpConnectionManager connectionManager) {
		return createRequest(serviceEndpoint, requestDefinition, headers, params, connectionManager, null, null);
	}

	/**
	 * 创建请求；
	 * 
	 * @param <T>               返回值类型；
	 * @param serviceEndpoint   服务终结点；
	 * @param requestDefinition 请求定义；
	 * @param headers           标准头部；
	 * @param params            标准参数；
	 * @return
	 */
	public static <T> HttpFunction<T> createRequest(HttpAddress serviceEndpoint,
			HttpRequestDefinition requestDefinition, Properties headers, Properties params,
			HttpConnectionManager connectionManager, EncodingPipe requestEncoder, DecodingPipe responseDecoder) {

		HttpProxy proxy = new HttpProxy(DEFAUL_HTTP_SERVICE_DEFINITION, requestDefinition);
		HttpConnection connection = connectionManager == null ? HttpConnectionManager.connect(serviceEndpoint)
				: connectionManager.create(serviceEndpoint);

		return new SimpleHttpFunction<>(proxy, (HttpProxyConnection) connection, headers, params, requestEncoder,
				responseDecoder);
	}

	private void initHttpService() {
		// 处理服务路径；
		ServiceProxy serviceAnno = this.serviceClass.getAnnotation(ServiceProxy.class);
		if (serviceAnno == null) {
			throw new IllegalHttpServiceDefinitionException(
					"The specific service was not tag with ServiceProxy annotation!");
		}

		// 解析服务路径；
		HttpServiceDefinition serviceDefinition = new HttpServiceDefinition(serviceAnno);
		// 一个HTTP服务中所有请求的路径的公共部分；
		String basePath = initHttpService(serviceDefinition);

		// 解析服务操作；
		Method[] mths = this.serviceClass.getMethods();
		for (Method mth : mths) {
			// 生成路径模板；
			HttpRequest requestAnno = mth.getAnnotation(HttpRequest.class);
			if (requestAnno == null) {
				// 未声明的方法不做解析；
				continue;
			}

			// 生成请求定义；
			HttpRequestDefinition requestDefinition = generateRequestDefinition(mth, requestAnno);

			HttpActionContext actionContext = createHttpAction(basePath, requestDefinition);
			if (actionContext != null) {
				httpActions.put(mth, actionContext);
			}
		}
	}

	/**
	 * 初始化 HTTP服务；
	 *
	 * @param serviceDefinition
	 * @return
	 */
	private String initHttpService(HttpServiceDefinition serviceDefinition) {
		String servicePath = serviceDefinition.getPath();
		servicePath = StringUtils.cleanPath(servicePath);
		if (TextUtils.isEmpty(servicePath)) {
			throw new IllegalHttpServiceDefinitionException(
					"Illegal path or no path was specified for the ServiceProxy!-- path=" + servicePath);
		}

		// 实例化服务的默认请求体参数转换器；
		Class<?> defaultRequestBodyConverterClazz = serviceDefinition.getDefaultRequestBodyConverter();
		if (defaultRequestBodyConverterClazz != null
				&& defaultRequestBodyConverterClazz != RequestBodyConverter.class) {
			if (RequestBodyConverter.class.isAssignableFrom(defaultRequestBodyConverterClazz)) {
				defaultRequestBodyConverter = (RequestBodyConverter) BeanUtils
						.instantiateClass(defaultRequestBodyConverterClazz);
			} else {
				throw new IllegalHttpServiceDefinitionException(
						"The specified default request body converter of service doesn't implement the interface "
								+ RequestBodyConverter.class.getName() + "!");
			}
		}

		// 初始化默认的回复处理器；
		this.defaultResponseHandler = initDefaultResponseHandler(serviceDefinition);

		// 初始化回复处理器工厂；
		this.responseHandlerFactory = initResponseHandlerFactory(serviceDefinition);

		return servicePath;
	}

	private ResponseHandlerFactory initResponseHandlerFactory(HttpServiceDefinition serviceDefinition) {
		// 初始化回复处理器工厂；
		Class<?> responseConverterFactoryClazz = serviceDefinition.getResponseConverterFactory();
		if (responseConverterFactoryClazz == ResponseConverterFactory.class) {
			// 未指定默认的回复转换器工厂；
			responseConverterFactoryClazz = null;
		}
		Class<?> responseHandlerFactoryClazz = serviceDefinition.getResponseHandlerFactory();
		if (responseHandlerFactoryClazz == ResponseHandlerFactory.class) {
			// 未指定默认的回复转换器工厂；
			responseHandlerFactoryClazz = null;
		}
		if (responseConverterFactoryClazz != null && responseHandlerFactoryClazz != null) {
			// 同时设置已废弃的定义属性和新的定义属性；
			// 以新的属性为准；
			responseConverterFactoryClazz = null;
		}
		// 此时，responseConverterFactoryClazz 或 responseHandlerFactoryClazz 最多只有一个不为空；

		ResponseHandlerFactory responseHandlerFactory = null;
		if (responseHandlerFactoryClazz != null) {
			if (ResponseHandlerFactory.class.isAssignableFrom(responseHandlerFactoryClazz)) {
				responseHandlerFactory = (ResponseHandlerFactory) BeanUtils
						.instantiateClass(responseHandlerFactoryClazz);
			} else {
				throw new IllegalHttpServiceDefinitionException(
						"The specified response handler factory of service doesn't implement the interface "
								+ ResponseHandlerFactory.class.getName() + "!");
			}
		} else if (responseConverterFactoryClazz != null) {
			if (ResponseConverterFactory.class.isAssignableFrom(responseConverterFactoryClazz)) {
				ResponseConverterFactory responseConverterFactory = (ResponseConverterFactory) BeanUtils
						.instantiateClass(responseConverterFactoryClazz);
				responseHandlerFactory = new ResponseConverterHandlerFactoryAdapter(responseConverterFactory);
			} else {
				throw new IllegalHttpServiceDefinitionException(
						"The specified response converter factory of service doesn't implement the interface " +
								ResponseConverterFactory.class.getName() + "!");
			}
		}
		return responseHandlerFactory;
	}

	private ResponseHandler initDefaultResponseHandler(HttpServiceDefinition serviceDefinition) {
		// 实例化服务的默认回复转换器；
		Class<?> defaultResponseConverterClazz = serviceDefinition.getDefaultResponseConverter();
		if (defaultResponseConverterClazz == ResponseConverter.class) {
			// 未指定默认的回复转换器；
			defaultResponseConverterClazz = null;
		}
		Class<?> defaultResponseHandlerClazz = serviceDefinition.getDefaultResponseHandler();
		if (defaultResponseHandlerClazz == ResponseHandler.class) {
			// 未指定默认的回复转换器；
			defaultResponseHandlerClazz = null;
		}
		if (defaultResponseConverterClazz != null && defaultResponseHandlerClazz != null) {
			// 同时设置已废弃的定义属性和新的定义属性；
			// 以新的属性为准；
			defaultResponseConverterClazz = null;
		}
		// 此时，defaultResponseConverterClazz 或 defaultResponseHandlerClazz 最多只有一个不为空；

		ResponseHandler defaultResponseHandler = null;
		if (defaultResponseConverterClazz != null) {
			if (ResponseConverter.class.isAssignableFrom(defaultResponseConverterClazz)) {
				ResponseConverter responseConverter = (ResponseConverter) BeanUtils
						.instantiateClass(defaultResponseConverterClazz);
				// 将 response converter 适配为 response handler ；
				defaultResponseHandler = ResponseConverterHandlerFactoryAdapter.createResponseHandler(responseConverter);
			} else {
				throw new IllegalHttpServiceDefinitionException(
						"The specified default response converter of service doesn't implement the interface "
								+ ResponseConverter.class.getName() + "!");
			}
		} else if (defaultResponseHandlerClazz != null) {
			if (ResponseHandler.class.isAssignableFrom(defaultResponseHandlerClazz)) {
				defaultResponseHandler = (ResponseHandler) BeanUtils
						.instantiateClass(defaultResponseHandlerClazz);
			} else {
				throw new IllegalHttpServiceDefinitionException(
						"The specified default response handler of service doesn't implement the interface "
								+ ResponseHandler.class.getName() + "!");
			}
		}
		return defaultResponseHandler;
	}

	private HttpRequestDefinition generateRequestDefinition(Method mth, HttpRequest requestAnno) {
		HttpRequestDefinition requestDefinition = new HttpRequestDefinition(mth, requestAnno);

		// 解析请求路径；
		String declaredActionPath = requestDefinition.getPath();
		String actionPath = StringUtils.cleanPath(declaredActionPath);
		if (TextUtils.isEmpty(actionPath)) {
			String defaultRequestPath = mth.getName();
			actionPath = defaultRequestPath;
		}
		requestDefinition.setPath(actionPath);

		// 解析请求参数；
		Class<?>[] paramTypes = mth.getParameterTypes();
		Annotation[][] paramAnnos = mth.getParameterAnnotations();

		for (int i = 0; i < paramTypes.length; i++) {
			RequestBody reqBodyAnno = findAnnotation(RequestBody.class, paramAnnos[i]);
			RequestParam reqParamAnno = findAnnotation(RequestParam.class, paramAnnos[i]);
			RequestParamList reqParamsAnno = findAnnotation(RequestParamList.class, paramAnnos[i]);
			PathParam pathParamAnno = findAnnotation(PathParam.class, paramAnnos[i]);
			if (hasConflictiveAnnotation(reqBodyAnno, reqParamAnno, reqParamsAnno, pathParamAnno)) {
				// 存在冲突的定义；
				throw new IllegalHttpServiceDefinitionException(
						"The argument[" + i + "] of action has conflictive definition!");
			}

			if (reqBodyAnno != null) {
				requestDefinition.addParam(paramTypes[i], reqBodyAnno);
			}
			if (reqParamAnno != null) {
				requestDefinition.addParam(paramTypes[i], reqParamAnno);

			}
			if (reqParamsAnno != null) {
				requestDefinition.addParam(paramTypes[i], reqParamsAnno);
			}
			if (pathParamAnno != null) {
				requestDefinition.addParam(paramTypes[i], pathParamAnno);
			}
		}
		return requestDefinition;
	}

	/**
	 * 解析请求定义；
	 * 
	 * @param basePath
	 * @param requestDefinition
	 * @param defaultPath
	 * @return
	 */
	private HttpActionContext createHttpAction(String basePath, HttpRequestDefinition requestDefinition) {
		String actionPath = requestDefinition.getPath();
		RequestPathTemplate pathTemplate = new RequestPathTemplate(basePath, actionPath);

		// 校验请求你方法；
		HttpMethod actionMethod = requestDefinition.getHttpMethod();
		if (actionMethod == null) {
			throw new IllegalHttpServiceDefinitionException("The http method of action was not specified!");
		}

		// 获取请求的内容类型；
		String contentType = requestDefinition.getContentType();
		if (contentType != null) {
			contentType = contentType.trim();
			if (contentType.length() == 0) {
				contentType = null;
			}
		}
		Class<?> reqParamFilterClass = requestDefinition.getRequestParamFilter();
		RequestParamFilter reqParamFilter = createRequestParamFilter(reqParamFilterClass);

		// HTTP 请求的回复要转换的Java类型
		// Class<?> responseType = mth.getReturnType();
		Class<?> responseType = requestDefinition.getResponseType();
		ResponseHandler responseHandler = createResponseHandler(requestDefinition, responseType);

		// 获取参数定义；
		// 参数列表中， RequestBody 最多只能定义一个；
		RequestBodyResolverComposite bodyResolverComposite = new RequestBodyResolverComposite();

		List<InputParam> params = requestDefinition.getParams();

		List<ParamDefinition<Param>> reqParamAnnos = new LinkedList<ParamDefinition<Param>>();
		List<ParamDefinition<ListParam>> reqParamMapAnnos = new LinkedList<ParamDefinition<ListParam>>();
		List<ParamDefinition<PathVariable>> pathParamAnnos = new LinkedList<ParamDefinition<PathVariable>>();
		for (int i = 0; i < params.size(); i++) {
			InputParam param = params.get(i);

			if (param instanceof Body) {
				RequestBodyResolver reqBodyResolver = createBodyResolver(
						new ParamDefinition<Body>(i, param.getParamTypes(), (Body) param));
				bodyResolverComposite.addRequestBodyResolver(reqBodyResolver);
			}
			if (param instanceof Param) {
				reqParamAnnos.add(new ParamDefinition<Param>(i, param.getParamTypes(), (Param) param));
			}
			if (param instanceof ListParam) {
				reqParamMapAnnos.add(new ParamDefinition<ListParam>(i, param.getParamTypes(), (ListParam) param));
			}
			if (param instanceof PathVariable) {
				pathParamAnnos.add(new ParamDefinition<PathVariable>(i, param.getParamTypes(), (PathVariable) param));
			}
		}
		RequestParamsResolver reqParamResolver = createRequestParamResolver(reqParamAnnos, reqParamMapAnnos);
		PathParamResolver pathParamResolver = createPathParamResolver(pathParamAnnos);

		// 获取声明的异常列表；
		Class<?>[] thrownExceptionTypes = requestDefinition.getThrownExceptionTypes();

		HttpActionContext actionContext = new HttpActionContext(requestDefinition.getHttpMethod(), contentType,
				pathTemplate, pathParamResolver, reqParamFilter, reqParamResolver, bodyResolverComposite,
				responseHandler, requestDefinition.getServiceMethod(), thrownExceptionTypes,
				requestDefinition.isResolveContentOnHttpError());
		return actionContext;
	}

	@SuppressWarnings("unchecked")
	private static <T> T findAnnotation(Class<T> clazz, Annotation[] annos) {
		for (Annotation annotation : annos) {
			if (clazz.isAssignableFrom(annotation.getClass())) {
				return (T) annotation;
			}
		}
		return null;
	}

	private RequestParamFilter createRequestParamFilter(Class<?> reqParamFilterClass) {
		// Class<?> reqParamFilterClass = reuestAnno.requestParamFilter();
		if (reqParamFilterClass == null || reqParamFilterClass == RequestParamFilter.class) {
			return NullRequestParamFilter.INSTANCE;
		}
		if (RequestParamFilter.class.isAssignableFrom(reqParamFilterClass)) {
			return (RequestParamFilter) BeanUtils.instantiateClass(reqParamFilterClass);
		} else {
			throw new IllegalHttpServiceDefinitionException(
					"The specified RequestParamFilter doesn't implement the interface "
							+ RequestParamFilter.class.getName() + "!");
		}
	}

	/**
	 * 创建回复结果转换器；
	 * 
	 * @param requestDefinition
	 * @param responseType
	 * @return
	 */
	private ResponseHandler createResponseHandler(HttpRequestDefinition requestDefinition, Class<?> responseType) {
		// if (Void.class.equals(responseType)) {
		// 	return NullResponseHandler.INSTANCE;
		// }

		Class<?> respConverterClass = requestDefinition.getResponseConverter();
		if (respConverterClass == ResponseConverter.class) {
			// 未设置方法级别的回复转换器；
			respConverterClass = null;
		}
		Class<?> respHandlerClass = requestDefinition.getResponseHandler();
		if (respHandlerClass == ResponseHandler.class) {
			// 未设置方法级别的回复处理器；
			respHandlerClass = null;
		}

		if (respHandlerClass != null && respConverterClass != null) {
			// 同时定义新旧两种回复处理器，则优先使用新的回复处理器；
			respConverterClass = null;
		}
		// 此时，respHandlerClass 或 respConverterClass 最多只有一个不为空；

		if (respHandlerClass == null && respConverterClass == null) {
			// 未设置方法级别的回复处理器，；
			if (defaultResponseHandler != null) {
				// 如果未设置方法级别的回复转换器，且设置了服务级别的默认回复转换器，则应用服务级别的默认回复转换器；
				return defaultResponseHandler;
			}
			// 根据回复类型自动创建默认名的回复转换器；
			if (responseHandlerFactory != null) {
				return responseHandlerFactory.createResponseHandler(requestDefinition, responseType);
			}
			// 未设置回复处理器工厂时，在最后会采用默认的回复处理器工程创建回复处理器；
		} else if (respConverterClass != null) {
			// 只由旧版本的定义：回复转换器；
			if (ResponseConverter.class.isAssignableFrom(respConverterClass)) {
				ResponseConverter responseConverter = (ResponseConverter) BeanUtils
						.instantiateClass(respConverterClass);
				return ResponseConverterHandlerFactoryAdapter.createResponseHandler(responseConverter);
			} else {
				throw new IllegalHttpServiceDefinitionException(
						"The specified response converter doesn't implement the interface "
								+ ResponseConverter.class.getName() + "!");
			}
		} else if (respHandlerClass != null) {
			// 只由新的定义：回复处理器；
			if (ResponseHandler.class.isAssignableFrom(respHandlerClass)) {
				ResponseHandler responseHandler = (ResponseHandler) BeanUtils.instantiateClass(respHandlerClass);
				return responseHandler;
			} else {
				throw new IllegalHttpServiceDefinitionException(
						"The specified response handler doesn't implement the interface "
								+ ResponseHandler.class.getName() + "!");
			}
		}
		// 最后由默认的的回复处理器工厂创建回复处理器；
		// create default response converter;
		return DefaultResponseHandlerFactory.INSTANCE.createResponseHandler(requestDefinition, responseType);
	}

	/**
	 * 创建路径参数解析器；
	 * 
	 * @param pathParamAnnos
	 * @return
	 */
	private PathParamResolver createPathParamResolver(List<ParamDefinition<PathVariable>> pathParamAnnos) {
		if (pathParamAnnos.size() == 0) {
			return PathParamResolvers.NONE_PATH_PARAM_RESOLVER;
		}
		List<ParamDefinition<PathParamAnnotation>> pathParamDefs = new LinkedList<ParamDefinition<PathParamAnnotation>>();
		for (ParamDefinition<PathVariable> entry : pathParamAnnos) {
			if (TextUtils.isEmpty(entry.getAnnotation().getName())) {
				throw new IllegalHttpServiceDefinitionException("The name of path parameter is empty!");
			}

			Class<?> converterClazz = entry.getAnnotation().getConverter();
			StringConverter converter = StringConverterFactory.instantiateStringConverter(converterClazz);
			ParamDefinition<PathParamAnnotation> argDefEntry = new ParamDefinition<PathParamAnnotation>(
					entry.getArgumentIndex(), entry.getArgumentType(),
					new PathParamAnnotation(entry.getAnnotation().getName(), converter));
			pathParamDefs.add(argDefEntry);
		}

		return PathParamResolvers.createResolver(pathParamDefs);
	}

	/**
	 * 创建请求参数解析器；
	 * 
	 * @param reqParamAnnos
	 * @return
	 */
	private RequestParamsResolver createRequestParamResolver(List<ParamDefinition<Param>> reqParamAnnos,
			List<ParamDefinition<ListParam>> reqParamsAnnos) {
		List<ParamDefinition<RequestParamAnnotation>> reqDefs = RequestParamAnnotation
				.resolveSingleParamDefinitions(reqParamAnnos);
		List<ParamDefinition<RequestParamListAnnotation>> reqMapDefs = RequestParamListAnnotation
				.resolveParamMapDefinitions(reqParamsAnnos);

		return ParamResolvers.createParamMapResolver(reqDefs, reqMapDefs);

	}

	/**
	 * @param paramIndex
	 * @param parameter
	 * @param reqBodyAnnoEntry
	 * @return
	 */
	private RequestBodyResolver createBodyResolver(ParamDefinition<Body> reqBodyAnnoEntry) {
		Class<?> converterClazz = reqBodyAnnoEntry.getAnnotation().getConverter();
		RequestBodyConverter converter = null;
		if (converterClazz == RequestBodyConverter.class || converterClazz == null) {
			converter = defaultRequestBodyConverter;
			if (converter == null) {
				// create default body converter;
				converter = new TypeAutoAdaptingRequestBodyConverter(reqBodyAnnoEntry.getArgumentType());
			}
		} else {
			if (!ClassUtils.isAssignable(RequestBodyConverter.class, converterClazz)) {
				throw new IllegalHttpServiceDefinitionException(
						"The specified body converter doesn't implement the interface "
								+ RequestBodyConverter.class.getName() + "!");
			}
			converter = (RequestBodyConverter) BeanUtils.instantiateClass(converterClazz);
		}

		RequestBodyAnnotation reqBodyDef = new RequestBodyAnnotation(reqBodyAnnoEntry.getAnnotation().isRequired(),
				converter);
		ParamDefinition<RequestBodyAnnotation> reqBodyDefEntry = new ParamDefinition<RequestBodyAnnotation>(
				reqBodyAnnoEntry.getArgumentIndex(), reqBodyAnnoEntry.getArgumentType(), reqBodyDef);
		return RequestBodyResolvers.createArgumentResolver(reqBodyDefEntry);
	}

	/**
	 * 检查传入的三个参数中是否有两个或两个以上为非空；
	 * <p>
	 * 参数只能有一种定义；
	 * 
	 * @param reqBodyAnno
	 * @param reqParamAnno
	 * @param pathParamAnno
	 * @return 有两个或两个以上为非空时返回 true；
	 * 
	 *         全部为 null 或只有一个为 null 时，返回 false；
	 */
	private static boolean hasConflictiveAnnotation(RequestBody reqBodyAnno, RequestParam reqParamAnno,
			RequestParamList reqParamsAnno, PathParam pathParamAnno) {
		return 1 < (reqBodyAnno == null ? 0 : 1) + (reqParamAnno == null ? 0 : 1) + (reqParamsAnno == null ? 0 : 1)
				+ (pathParamAnno == null ? 0 : 1);
	}

	/**
	 * 解析被调用的方法，映射为 http 请求；
	 */
	private Object invoke(HttpAddress serviceEndpoint, CloseableHttpClient httpClient,
			HttpActionContext actionContext, Properties headers, Properties params,
			Object[] args, EncodingPipe requestEncoder, DecodingPipe responseDecoder) throws Throwable {
		return invoke(serviceEndpoint, httpClient, actionContext, null, null, headers, args, params, requestEncoder,
				responseDecoder,
				null);
	}

	/**
	 * 解析被调用的方法，映射为 http 请求；
	 */
	private Object invoke(HttpAddress serviceEndpoint, CloseableHttpClient httpClient,
			Method method, RequestHeadersProvider headersProvider, HeaderEntry[] headers,
			Object[] args, EncodingPipe requestEncoder, DecodingPipe responseDecoder,
			HttpServiceContext serviceContext) throws Throwable {
		HttpActionContext actionContext = httpActions.get(method);
		return invoke(serviceEndpoint, httpClient, actionContext, headersProvider, headers, null, args, null,
				requestEncoder, responseDecoder,
				serviceContext);
	}

	/**
	 * 解析被调用的方法，映射为 http 请求；
	 */
	private Object invoke(HttpAddress serviceEndpoint,
			CloseableHttpClient httpClient, HttpActionContext actionContext,
			RequestHeadersProvider headersProvider, HeaderEntry[] headers, Properties extHeaders, Object[] args,
			Properties extParams, EncodingPipe requestEncoder, DecodingPipe responseDecoder,
			HttpServiceContext serviceContext) throws Throwable {
		if (actionContext == null) {
			throw new UnsupportedOperationException("The invoked method was not a service action!");
		}
		try {
			ServcieHttpRequest serviceRequest = createServiceHttpRequest(serviceEndpoint, actionContext, args,
					requestEncoder);
			// 设置额外的请求参数；
			if (extParams != null && !extParams.isEmpty()) {
				serviceRequest.setParams(extParams);
			}

			HttpUriRequest httpRequest = buildHttpRequest(serviceRequest);
			
			// 设置预定义的头部；
			applyHeaders(httpRequest, headers);
			// 设置解析请求生成的头部；
			applyHeaders(httpRequest, serviceRequest.getHeaders());
			// 设置额外的头部参数，可覆盖其它预定义的头部；
			if (extHeaders != null && !extHeaders.isEmpty()) {
				applyHeaders(httpRequest, extHeaders);
			}

			// 解析动态头部参数；
			// 与静态参数重名时，覆盖静态参数；
			if (headersProvider != null) {
				com.linkgie.galaxyframework.httpproxy.HttpHeaders customHeaders = headersProvider
						.generate(serviceRequest);
				if (customHeaders != null) {
					ParamEntry[] headerEntries = customHeaders.getAll();
					if (headerEntries != null) {
						for (int i = 0; i < headerEntries.length; i++) {
							ParamEntry headerEntry = headerEntries[i];
							// 重名时，覆盖静态参数；
							httpRequest.setHeader(headerEntry.getName(), headerEntry.getValue());
						}
					}
				}
				// AuthorizationHeader auth = authorizationHeaderResolver.generate(message);
				// // 设置认证属性；
				// buildAuthorization(httpRequest, auth);
			}

			// 设置默认的 Content-Type；
			Header[] contentTypeHeaders = httpRequest.getHeaders(HttpHeaders.CONTENT_TYPE);
			if (contentTypeHeaders == null || contentTypeHeaders.length == 0) {
				httpRequest.setHeader(HttpHeaders.CONTENT_TYPE, DEFAULT_CONTENT_TYPE);
			}

			CloseableHttpResponse response = httpClient.execute(httpRequest);
			try {
				// // 引发 http 异常；
				// // 300 - 399 : 重定向消息；
				// // 400 - 499 : 客户端错误响应；
				// // 500 - 599 : 服务端错误响应；
				// if (response.getStatusLine().getStatusCode() >= 400) {
				// 	processAndThrowHttpException(actionContext, serviceRequest, response);
				// 	// 注：实际不会执行到此，因为上一步已抛出异常；
				// 	return null;
				// }
				// // 处理重定向；
				// if (response.getStatusLine().getStatusCode() >= 300) {
				// 	processAndThrowRedirectException(actionContext, serviceRequest, response);
				// 	// 注：实际不会执行到此，因为上一步已抛出异常；
				// 	return null;
				// }

				ServiceHttpResponse serviceResponse = new ServiceHttpResponse(response, responseDecoder);

				ServiceInvocationContext invocationContext = new ServiceInvocationContextImpl(serviceContext,
						actionContext);
				Object respObject = actionContext.getResponseHandler().handleResponse(serviceRequest, serviceResponse,
						invocationContext);
				return respObject;
			} finally {
				response.close();
			}
		} catch (HttpRequestException e) {
			throw e;
		} catch (Exception e) {
			if (isThownException(e, actionContext)) {
				throw e;
			}
			if (e instanceof HttpRequestException) {
				throw (HttpRequestException) e;
			}
			throw new HttpRequestException(e.getMessage(), e);
		}
	}

	private void applyHeaders(HttpUriRequest httpRequest, HeaderEntry[] headers) {
		if (headers == null) {
			return;
		}
		for (HeaderEntry header : headers) {
			httpRequest.setHeader(header.getName(), header.getValue());
		}
	}

	private void applyHeaders(HttpUriRequest httpRequest, Properties headerProperties) {
		Set<String> names = headerProperties.stringPropertyNames();
		for (String name : names) {
			httpRequest.setHeader(name, headerProperties.getProperty(name));
		}
	}

	/**
	 * 判断指定的异常是否属于可直接抛出的异常；
	 * <p>
	 * 对于由服务接口的方法定义的 HTTP 操作而言，如果是属于接口方法上 throws 声明的异常，则返回 true ，否则，返回 false；
	 * 
	 * @param e
	 * @param actionContext
	 * @return
	 */
	private boolean isThownException(Exception e, HttpActionContext actionContext) {
		Class<?> exType = e.getClass();
		Class<?>[] thrownExTypes = actionContext.getThrownExceptionTypes();
		if (thrownExTypes != null) {
			for (Class<?> thrExType : thrownExTypes) {
				if (thrExType.isAssignableFrom(exType)) {
					return true;
				}
			}
		}
		return false;
	}


	private ServcieHttpRequest createServiceHttpRequest(HttpAddress serviceEndpoint, HttpActionContext actionContext,
			Object[] args, EncodingPipe requestEncoder) throws IOException {
		ServcieHttpRequest request;
		switch (actionContext.getRequestMethod()) {
			case GET:
				request = createGetMessage(serviceEndpoint, actionContext, args);
				break;
			case POST:
			case PUT:
				request = createPostOrPutMessage(serviceEndpoint, actionContext, args, requestEncoder);
				break;
			case DELETE:
				request = createDeleteMessage(serviceEndpoint, actionContext, args, requestEncoder);
				break;
			default:
				throw new UnsupportedOperationException(
						"Unsupported http method '" + actionContext.getRequestMethod() + "'!");
		}
		if (actionContext.getContentType() != null) {
			request.setHeader(HttpHeaders.CONTENT_TYPE, actionContext.getContentType());
		}
		return request;
	}

	/**
	 * 创建请求；
	 * 
	 * @param actionContext
	 * @param args
	 * @return
	 */
	private HttpUriRequest buildHttpRequest(ServcieHttpRequest message) {
		ByteBuffer bodyBytes = null;
		if (message.getBody() != null) {
			bodyBytes = message.getBody();
		}
		HttpParams params = message.getParams();
		switch (message.getMethod()) {
			case GET:
				URIBuilder uriBuilder = new URIBuilder(message.getUri());
				if (params != null && !params.isEmpty()) {
					ParamEntry[] paramValues = params.getAll();
					for (ParamEntry param : paramValues) {
						uriBuilder.addParameter(param.getName(), param.getValue());
					}
				}
				URI requestUri;
				try {
					requestUri = uriBuilder.build();
				} catch (URISyntaxException e) {
					throw new IllegalStateException(e.getMessage(), e);
				}
				HttpGet httpGet = new HttpGet(requestUri);

				//TODO: 未充分测试阻止重定向策略的效果；
				// // 禁止重定向；
				// RequestConfig requestConfig = RequestConfig.custom().setRedirectsEnabled(false).build();
				// httpGet.setConfig(requestConfig);

				return httpGet;
			case POST:
				HttpPost httppost = new HttpPost(message.getUri());
				if (params != null && !params.isEmpty()) {
					// 以 form 表单提交；
					ParamEntry[] propNames = params.getAll();
					List<NameValuePair> formParams = new ArrayList<NameValuePair>();
					for (ParamEntry param : propNames) {
						formParams.add(new BasicNameValuePair(param.getName(), param.getValue()));
					}
					UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(formParams, Consts.UTF_8);
					httppost.setEntity(formEntity);
					// 设置默认的 Content-Type；
					httppost.setHeader(formEntity.getContentType());
				}
				if (bodyBytes != null) {
					// 查询参数以 Stream body 方式提交；
					ByteArrayEntity entity = new ByteArrayEntity(bodyBytes.array());
					// HttpEntity streamEntity = new InputStreamEntity(bodyStream);
					httppost.setEntity(entity);
					// 设置默认的 Content-Type；
					httppost.setHeader(entity.getContentType());
				}
				return httppost;
			case PUT:
				HttpPut httpput = new HttpPut(message.getUri());
				if (params != null && !params.isEmpty()) {
					// 以 form 表单提交；
					ParamEntry[] paramValues = params.getAll();
					List<NameValuePair> formParams = new ArrayList<NameValuePair>();
					for (ParamEntry param : paramValues) {
						formParams.add(new BasicNameValuePair(param.getName(), param.getValue()));
					}
					UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(formParams, Consts.UTF_8);
					httpput.setEntity(formEntity);
				}
				if (bodyBytes != null) {
					// 查询参数以 Stream body 方式提交；
					ByteArrayEntity entity = new ByteArrayEntity(bodyBytes.array());
					// HttpEntity streamEntity = new InputStreamEntity(bodyStream);
					httpput.setEntity(entity);
				}
				return httpput;
			case DELETE:
				// HttpDelete httpDelete = new HttpDelete(uri);
				LocalHttpDelete httpDelete = new LocalHttpDelete(message.getUri());
				// 查询参数以 delete body 方式提交
				if (bodyBytes != null) {
					ByteArrayEntity entity = new ByteArrayEntity(bodyBytes.array());
					// HttpEntity entity = new InputStreamEntity(bodyStream);
					httpDelete.setEntity(entity);
				}
				// HttpEntity entity = new InputStreamEntity(bodyStream);
				// httpDelete.setEntity(entity);
				return httpDelete;
			default:
				throw new UnsupportedOperationException("Unsupported http method '" + message.getMethod() + "'!");
		}
	}

	// /**
	// * 设置http请求头的Authorization属性
	// *
	// * @param request
	// * @param header
	// */
	// private void buildAuthorization(HttpUriRequest request, HeaderEntry header) {
	// request.addHeader(header.getName(), header.getValue());
	// }

	/**
	 * 创建 http post 请求；
	 * 
	 * @param actionContext
	 * @param args
	 * @return
	 * @throws IOException
	 */
	// private HttpServiceRequest resolvePostRequest(ServiceActionContext
	// actionContext, Object[] args)
	// throws IOException {
	// Map<String, String> pathParams =
	// actionContext.getPathParamResolver().resolve(args);
	// Properties reqParams =
	// actionContext.getRequestParamResolver().resolve(args);
	// InputStream inputStream =
	// actionContext.getRequestBodyResolver().resolve(args);
	// URI uri = actionContext.getPathTemplate().generateRequestURI(pathParams,
	// reqParams,
	// ServiceActionContext.DEFAULT_CHARSET);
	// byte[] bytes = BytesUtils.copyToBytes(inputStream);
	// return new HttpServiceRequest(HttpMethod.POST, uri,
	// ByteBuffer.wrap(bytes));
	// }

	/**
	 * 创建http put请求
	 * 
	 * @param actionContext
	 * @param args
	 * @return
	 * @throws IOException
	 */
	// private HttpServiceRequest resolvePutRequest(ServiceActionContext
	// actionContext, Object[] args) throws IOException {
	// Map<String, String> pathParams =
	// actionContext.getPathParamResolver().resolve(args);
	// Properties reqParams =
	// actionContext.getRequestParamResolver().resolve(args);
	// InputStream inputStream =
	// actionContext.getRequestBodyResolver().resolve(args);
	// URI uri = actionContext.getPathTemplate().generateRequestURI(pathParams,
	// reqParams,
	// ServiceActionContext.DEFAULT_CHARSET);
	// byte[] bytes = BytesUtils.copyToBytes(inputStream);
	// return new HttpServiceRequest(HttpMethod.PUT, uri,
	// ByteBuffer.wrap(bytes));
	// }

	private ServcieHttpRequest createPostOrPutMessage(HttpAddress serviceEndpoint, HttpActionContext actionContext,
			Object[] args, EncodingPipe requestEncoder) throws IOException {
		// 解析路径参数；
		Map<String, String> pathParams = actionContext.getPathParamResolver().resolve(args);
		HttpMethod httpMethod = actionContext.getRequestMethod();

		// 解析 RequestBody；
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		actionContext.getRequestBodyResolver().resolve(args, out);
		byte[] bodyBytes = out.toByteArray();
		if (requestEncoder != null) {
			bodyBytes = requestEncoder.encode(bodyBytes);
		}

		boolean noBody = bodyBytes.length == 0;

		// 解析 RequestParam；
		HttpParams reqParams = actionContext.getRequestParamResolver().resolve(args);
		boolean noReqParams = reqParams.isEmpty();
		actionContext.getRequestParamFilter().filter(httpMethod, reqParams);

		// 如果只有 RequestBody 标注的参数，则以 RequestBody 参数的序列化输出作为请求体；
		if ((!noBody) && noReqParams) {
			URI uri = actionContext.getPathTemplate().generateRequestURI(serviceEndpoint, pathParams, new HttpParams(),
					HttpActionContext.DEFAULT_CHARSET);
			ByteBuffer body = ByteBuffer.wrap(bodyBytes);
			return new ServcieHttpRequest(httpMethod, uri, null, body, args);
		}
		// 如果没有 RequestBody 标注的参数，只有 RequestParam ，则 RequestParam 通过请求体以表单格式提交；
		if (noBody && (!noReqParams)) {
			URI uri = actionContext.getPathTemplate().generateRequestURI(serviceEndpoint, pathParams, new HttpParams(),
					HttpActionContext.DEFAULT_CHARSET);
			return new ServcieHttpRequest(httpMethod, uri, reqParams, null, args);
		}

		// 如果同时有 RequestBody 标注的参数和 RequestParam 标注的参数，则以 RequestBody
		// 参数的序列化输出作为请求体，RequestParam 作为 URL 参数；
		if ((!noBody) && (!noReqParams)) {
			URI uri = actionContext.getPathTemplate().generateRequestURI(serviceEndpoint, pathParams, reqParams,
					HttpActionContext.DEFAULT_CHARSET);
			ByteBuffer body = ByteBuffer.wrap(bodyBytes);
			return new ServcieHttpRequest(httpMethod, uri, null, body, args);
		}

		// 既没有 RequestBody，也没有 RequestParam；
		URI uri = actionContext.getPathTemplate().generateRequestURI(serviceEndpoint, pathParams, new HttpParams(),
				HttpActionContext.DEFAULT_CHARSET);
		return new ServcieHttpRequest(httpMethod, uri, null, null, args);
	}

	/**
	 * 创建http get请求
	 * 
	 * @param actionContext
	 * @param args
	 * @return
	 */
	private ServcieHttpRequest createGetMessage(HttpAddress serviceEndpoint, HttpActionContext actionContext,
			Object[] args) {
		Map<String, String> pathParams = actionContext.getPathParamResolver().resolve(args);
		HttpParams reqParams = actionContext.getRequestParamResolver().resolve(args);
		URI uri = actionContext.getPathTemplate().generateRequestURI(serviceEndpoint, pathParams, reqParams,
				HttpActionContext.DEFAULT_CHARSET);
		// 对于 get 请求，请求参数已经编码到 URI 中，所以不必再传递出去进行处理；
		return new ServcieHttpRequest(HttpMethod.GET, uri, null, null, args);
	}

	/**
	 * 创建http delete请求
	 * 
	 * @param actionContext
	 * @param args
	 * @return
	 * @throws IOException
	 */
	private ServcieHttpRequest createDeleteMessage(HttpAddress serviceEndpoint, HttpActionContext actionContext,
			Object[] args, EncodingPipe requestEncoder) throws IOException {
		Map<String, String> pathParams = actionContext.getPathParamResolver().resolve(args);

		HttpParams reqParams = actionContext.getRequestParamResolver().resolve(args);

		ByteArrayOutputStream out = new ByteArrayOutputStream();
		actionContext.getRequestBodyResolver().resolve(args, out);
		byte[] bodyBytes = out.toByteArray();
		if (requestEncoder != null) {
			bodyBytes = requestEncoder.encode(bodyBytes);
		}

		URI uri = actionContext.getPathTemplate().generateRequestURI(serviceEndpoint, pathParams, reqParams,
				HttpActionContext.DEFAULT_CHARSET);

		ByteBuffer body = bodyBytes.length == 0 ? null : ByteBuffer.wrap(bodyBytes);
		return new ServcieHttpRequest(HttpMethod.DELETE, uri, null, body, args);
	}

	private static class SimpleHttpFunction<T> implements HttpFunction<T> {
		private HttpProxy httpProxy;

		private HttpProxyConnection connection;

		private Properties defaultHeaders;

		private Properties defaultParams;

		private EncodingPipe requestEncoder;
		private DecodingPipe responseDecoder;

		public SimpleHttpFunction(HttpProxy httpProxy, HttpProxyConnection connection, Properties defaultHeader,
				Properties defaultParams, EncodingPipe requestEncoder, DecodingPipe responseDecoder) {
			this.httpProxy = httpProxy;
			this.connection = connection;
			this.defaultHeaders = defaultHeader;
			this.defaultParams = defaultParams;
			this.requestEncoder = requestEncoder;
			this.responseDecoder = responseDecoder;
		}

		@SuppressWarnings("unchecked")
		@Override
		public T request(Properties headers, Properties params, Object[] args) throws HttpRequestException {
			Properties requestHeader = new Properties();
			Properties requestParams = new Properties();
			// 合并默认头部；
			if (defaultHeaders != null) {
				requestHeader.putAll(defaultHeaders);
			}
			if (defaultParams != null) {
				requestParams.putAll(defaultParams);
			}
			// 合并动态头部；
			if (headers != null) {
				requestHeader.putAll(headers);
			}
			// 合并动态参数；
			if (params != null) {
				requestParams.putAll(params);
			}

			try {
				return (T) httpProxy.invoke(connection.getEndpoint(), connection.getHttpClient(),
						httpProxy.singletonAction,
						defaultHeaders, requestParams, args, requestEncoder, responseDecoder);
			} catch (HttpRequestException e) {
				throw e;
			} catch (Throwable e) {
				throw new HttpRequestException(e.getMessage(), e);
			}
		}

	}

	private static class ServiceInvocationHandler implements InvocationHandler, HttpServiceContext, HttpServiceClient {

		private HttpProxy httpProxy;

		private HttpProxyConnection connection;

		/**
		 * 动态头部；
		 */
		private RequestHeadersProvider headersProvider;

		/**
		 * 静态头部；
		 */
		private HeaderEntry[] headers;

		/**
		 * 请求编码器；
		 */
		private EncodingPipe requestEncoder;

		/**
		 * 响应解码器；
		 */
		private DecodingPipe responseDecoder;

		/**
		 * 绑定数据；
		 */
		private Object bindingData;

		public ServiceInvocationHandler(HttpProxy httpProxy, HttpProxyConnection connection,
				RequestHeadersProvider headersProvider, HeaderEntry[] headers, EncodingPipe requestEncoder,
				DecodingPipe responseDecoder,
				Object bindingData) {
			this.httpProxy = httpProxy;
			this.connection = connection;
			this.headersProvider = headersProvider;
			this.headers = headers;
			this.requestEncoder = requestEncoder;
			this.responseDecoder = responseDecoder;
			this.bindingData = bindingData;
		}

		@Override
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			if (method.getDeclaringClass() == HttpServiceClient.class) {
				return method.invoke(this, args);
			}
			return httpProxy.invoke(connection.getEndpoint(), connection.getHttpClient(), method, headersProvider,
					headers, args, requestEncoder, responseDecoder, this);
		}

		@Override
		public Class<?> getServiceClasss() {
			return httpProxy.serviceClass;
		}

		@Override
		public Object getProxyBindingData() {
			return bindingData;
		}

		@Override
		public HttpAddress getRemoteAddress() {
			return connection.getEndpoint();
		}

		@Override
		public void close() throws IOException {
			connection.close();
			;
		}
	}

	@SuppressWarnings("unused")
	private static class HttpServiceContextImpl implements HttpServiceContext {

		private Class<?> serviceClass;

		private Object proxyBindingData;

		public HttpServiceContextImpl(Class<?> serviceClass, Object proxyBindingData) {
			this.serviceClass = serviceClass;
			this.proxyBindingData = proxyBindingData;
		}

		@Override
		public Class<?> getServiceClasss() {
			return serviceClass;
		}

		@Override
		public Object getProxyBindingData() {
			return proxyBindingData;
		}

	}
}
